package com.bee.study.web;

import com.bee.study.entity.Cars;
import com.bee.study.repository.CarsRepository;
import com.bee.study.util.JsonUtils;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
import org.elasticsearch.search.aggregations.metrics.cardinality.Cardinality;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @version 1.0.0
 * @Author yong.Mr
 * @data 2019-8-9
 */
@RestController
@RequestMapping("/cars")
public class AggregationTest {

    @Autowired
    private CarsRepository carsRepository;


    @RequestMapping("/terms")
    public String termsAggs(){
//        NativeSearchQueryBuilder query = new NativeSearchQueryBuilder();
//        query.withQuery(QueryBuilders.termsQuery("", Lists.newArrayList()))
//                .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.ASC))
//        .withPageable(PageRequest.of(0,10, Sort.by(Sort.Direction.ASC,"updateTime")));
//        NativeSearchQuery build = query.build();
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withSourceFilter(new FetchSourceFilter(new String[]{""}, null))
                .addAggregation(AggregationBuilders.terms("popu_color").field("color")
                        .subAggregation(AggregationBuilders.terms("maker").field("make"))
                        .subAggregation(AggregationBuilders.avg("avg_price").field("price"))
                        .subAggregation(AggregationBuilders.stats("stats_price").field("price")))
                .build();
        System.out.println(JsonUtils.objectToJson(searchQuery.toString()));
        AggregatedPage<Cars> search = (AggregatedPage<Cars>)carsRepository.search(searchQuery);
        StringTerms agg = (StringTerms)search.getAggregation("popu_color");
        List<StringTerms.Bucket> buckets = agg.getBuckets();
        buckets.stream().forEach(x -> {
            System.out.println(x.getKeyAsString() + "---" + x.getDocCount());
            InternalAvg avg = (InternalAvg) x.getAggregations().getAsMap().get("avg_price");
            System.out.println(avg.getValue());
            StringTerms maker = (StringTerms)x.getAggregations().asMap().get("maker");
            maker.getBuckets().stream().forEach(ma -> {
                System.out.println(ma.getKeyAsString() + "****" + ma.getDocCount());
//                System.out.println(ma.getKeyAsNumber());
            });
        });
        //  打印总条数 totale
        search.getTotalElements();
        System.out.println();
        // 打印总页数
        search.getTotalPages();
        // 每页大小
        search.getSize();
        // 当前页
        search.getNumber();
        // 获取符合条件的内容
        List<Cars> content = search.getContent();
        System.out.println(content.toString());
        // 获取分页对象
        Pageable pageable = search.getPageable();
        // 获取排序对象
        Sort sort = search.getSort();
        System.out.println();
        return JsonUtils.objectToJson(searchQuery.toString());
    }

    /**
     * 去重聚合cardinality
     * @return
     */
    @RequestMapping("/cardinality")
    public String cardinalityTest(){
        // dateHistogram  Aggregation 是时间柱状图聚合，按照天来聚合 ， dataAgg 为聚合结果的名称，需要聚合sold 的字段名称
        // 对时间梯度分组之后的桶内数据进行去重cardinality 用来去重
        NativeSearchQuery nativeSearchQueryBuilder = new NativeSearchQueryBuilder()
                .withSourceFilter(new FetchSourceFilter(new String[]{""},null))
                .withPageable(PageRequest.of(0,20,Sort.by(Sort.Order.desc("price"))))
                .addAggregation(AggregationBuilders.dateHistogram("dateAgg").field("sold").
                        dateHistogramInterval(DateHistogramInterval.DAY).format("yyyy-MM-dd").minDocCount(1)
//                        .extendedBounds(new ExtendedBounds("2014-01-01","2014-01-01"))
                    .subAggregation(AggregationBuilders.cardinality("car_name").field("color")))
                .build();
        // 将Page<Cars>强转为AggregatedPage<Cars>, 可以直接获取聚合的数据
        AggregatedPage<Cars> searchResult = (AggregatedPage<Cars>)carsRepository.search(nativeSearchQueryBuilder);
        //                 Aggregations aggregations = searchResult.getAggregations();
//        Aggregation dateAgg = aggregations.asMap().get("dateAgg");
//        Aggregation dateAgg1 = searchResult.getAggregation("dateAgg");
        // 强转为Histogram, 可以获取bucket
        Histogram dateAgg = (Histogram)searchResult.getAggregation("dateAgg");
        List<Histogram.Bucket> buckets = (List<Histogram.Bucket>)dateAgg.getBuckets();
        buckets.stream().forEach(x -> {
            String keyAsString = x.getKeyAsString();
            long docCount = x.getDocCount();
            System.out.println(keyAsString + "---" + docCount);
            Aggregations car_nameAggre = x.getAggregations();
            Cardinality car_name = (Cardinality)car_nameAggre.getAsMap().get("car_name");
            long value = car_name.getValue();
            System.out.println(value);
        });
        return null;
    }
}
